package com.cloud.mkz.core.mvc.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.cloud.mkz.core.common.utils.RedisUtil;
import com.cloud.mkz.core.mvc.interceptor.BasicInterceptor;
import com.cloud.mkz.core.mvc.mybatis.SqlFilterArgumentResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET;

/**
 * SpringMvc 配置类
 *
 * @author kuangjianyu
 * @date 2021-01-27
 */
@Configuration(proxyBeanMethods = true)
@ConditionalOnWebApplication(type = SERVLET)
@RequiredArgsConstructor
public class WebMvcConfiguration implements WebMvcConfigurer {
	private final RedisUtil redisUtil;
	@Value("${interceptor.use-oauth:false}")
	private Boolean useOauth;

	@Bean
	public BasicInterceptor getBasicInterceptor(){
		return new BasicInterceptor();
	}
	
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    	//注册自定义拦截器，添加拦截路径和排除拦截路
		registry.addInterceptor(getBasicInterceptor())
				.addPathPatterns("/**")
				.excludePathPatterns("api/path/login")
				.excludePathPatterns("/dict/type")
				.excludePathPatterns("/get")
				.excludePathPatterns("/v2/api-docs")
				.excludePathPatterns("/passport/**");
    }

	/**
	 * SQL 过滤器避免SQL 注入
	 * @param argumentResolvers
	 */
	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
		argumentResolvers.add(new SqlFilterArgumentResolver());
	}
    /**
	 * 请求参数过滤器
     * @return FilterRegistrationBean
     */
//	@Bean
//    public FilterRegistrationBean<RequestParameterFilter> requestParameterFilter() {
//		FilterRegistrationBean<RequestParameterFilter> registration = new FilterRegistrationBean<RequestParameterFilter>();
//		registration.setFilter(new RequestParameterFilter());
//		registration.addUrlPatterns("/*");
//		registration.addInitParameter("paramName", "paramValue");
//		registration.setName("requestParameterFilter");
//		registration.setOrder(0);
//		return registration;
//    }

	/** 重写自定义消息转换器，此方法仅在启动创建容器时加载一次
	 * mwj
	 *   对于String类型的对象，如果其值为null时将其在序列化的时转为“”
	 */
	@Override
	public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建fastJson消息转换器
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //创建配置类
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
		ValueFilter valueFilter = (o, s, ov) -> {
			if (null == ov) {
				ov = "";
			}
			if (ov instanceof LocalDateTime){
				ov = ((LocalDateTime) ov).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
			}
			return ov;
		};
		fastJsonConfig.setSerializeFilters(valueFilter);

		//修改配置返回内容的过滤
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteMapNullValue,
                //String为null转为空
                SerializerFeature.WriteNullStringAsEmpty,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteEnumUsingName
        );
        //设置相应媒体类型
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        fastConverter.setSupportedMediaTypes(supportedMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        /*
     	* 将fastjson添加到视图消息转换器列表内，设置为7将优先级设置为默认json转换器之前，如果不写数字可以先
     	* clear掉然后顺序add父类转换器
        * */
        converters.add(7, fastConverter);
	}
}